﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Data.SqlTypes;
using System.Data.SqlClient;

using Noris.Schedule.Support;
using Noris.Schedule.Support.Data;
using Noris.Schedule.Support.Sql;
using Noris.Schedule.Support.DataFace;

using Noris.Schedule.Planning.DataFace;

namespace Noris.Schedule.Planning.ProcessData
{
	#region CLASS MaterialDataCls : ucelený systém osy S = skladové karty a vývoj zásob
	/// <summary>
	/// Třída, která implementuje kompletní systém skladových zásob.
	/// Obsahuje data všech plánovacích jednotek ze všech skladů.
	/// </summary>
	internal partial class MaterialDataCls : PlanningComponentCls, IDisposable
	{
		#region ČTENÍ DAT PLÁNU Z DATABÁZE
		/// <summary>
		/// Metoda zajistí načtení svých plánovacích dat z databáze.
		/// Nenačítají se číselníky ani definice, protože v této době (DataLoad()) jsou již číselníky načteny 
		/// (metoda DataPrepare() již  proběhla).
		/// Neprovádí se DataClear, protože to proběhlo centrálně před DataLoad (viz PlanningDataCls.DataLoad()).
		/// Pro data tohoto modulu (MaterialData) se vlastně nic nenačítá, ale po načtení dat je třeba provést finalizaci (metodou DataLoadEnd()).
		/// </summary>
		internal override void DataLoad()
		{
		}
		/// <summary>
		/// Finalizuje načtená data modulu materiál.
		/// Zavolá finalizaci svých skladových karet.
		/// </summary>
		internal void DataLoadEnd()
		{
			foreach (StockCardCls stockCard in this._StockCardDict.Values)
				stockCard.DataLoadEnd();
		}
		#endregion
		#region UKLÁDÁNÍ DAT DO DATABÁZE (Clear, Recalc, Save)
		/// <summary>
		/// Metoda zajistí uložení svých dat do databáze
		/// </summary>
		internal void SaveData()
		{
			this._SaveDeleteOldRecords();
			this._RecalcDisponibleQty(false);
			this._SaveDataPlanUnitS();
			this._SaveDataStockLevel();
            this.DataIndexing(true);
		}
		/// <summary>
		/// Smaže všechny záznamy z databáze, které se týkají aktuální verze plánu, a které obhospodařuje tento modul skladových zásob.
		/// V současnosti nic takového nemažeme, stavy skladů se nulují a přepočítávají vždy, ukládají jen někdy this.PlanningParameters.SaveStockLevelData, ale nemažou nikdy.
		/// </summary>
		private void _SaveDeleteOldRecords()
		{ }
		/// <summary>
		/// Zajistí ukládání dat plánovacích jednotek (jejich koncové disponibilní zásoby) do databáze.
		/// Pozor, ukládají se i záznamy nově vytvořené (nové plánovací jednotky), což vede k nutnosti po dokončení ukládání přeindexovat data PJ!!!
		/// </summary>
		private void _SaveDataPlanUnitS()
		{
            // Data PJ-S budu ukládat vždy. Podle hodnoty this.PlanningParameters.SaveStockLevelData budu ukládat: true => vše / false => jen nově založené záznamy:
            bool saveDispQty = this.ParentPlanning.PlanningParameters.SaveStockLevelData;
            using (var scope = Steward.TraceScopeBegin(Constants.TraceTypeMaterial, "Save.PlanUnitS", Constants.TraceKeyWordAplScheduler, "PlanUnitS.Count = " + this._PlanUnitSDict.Count.ToString()))
            {
                scope.SuppressInnerTrace(null, null, "SQL");
                foreach (PlanUnitSCls planUnitS in this._PlanUnitSDict.Values)
                {
                    if (planUnitS.CisloSubjektu <= 0 || saveDispQty)
                        this._SaveDataPlanUnitSOne(planUnitS, saveDispQty);
                }
            }

            // Invaliduji indexy (systém si je vytvoří nové):
            // Ne.
            // Museli bychom ve všech datech, která obsahují starý klíč PJ-S (záporný) tento klíč nahradit novým klíčem (kladným číslem subjektu).
		}
        /// <summary>
        /// Uloží do databáze data jedné dané plánovací jednotky S osy.
        /// Volitelně ukládá atributy s disponibilním množstvím, podle parametru saveDispQty).
        /// </summary>
        /// <param name="saveDispQty"></param>
        private void _SaveDataPlanUnitSOne(PlanUnitSCls planUnitS, bool saveDispQty)
        {
            planUnitS.Save();
        }
		/// <summary>
		/// Zajistí ukládání dat stavu skladů (jejich koncové disponibilní zásoby) do databáze.
		/// Pozor, pokud byl uložen stav skladu PJ pro nově zakládanou PJ, je třeba dohledat její permanentní klíč a ten vepsat do záznamu stav skladu.
		/// </summary>
		private void _SaveDataStockLevel()
		{
			// Ukládání se bude provádět jen tehdy, pokud v parametrech procesu je příznak "SaveStockLevelData == true":
            if (!this.ParentPlanning.PlanningParameters.SaveStockLevelData) return;

            using (var scope = Steward.TraceScopeBegin(Constants.TraceTypeMaterial, "Save.StockLevel", Constants.TraceKeyWordAplScheduler, "StockLevel.Count = " + this._StockCardDict.Count.ToString()))
            {
                scope.SuppressInnerTrace(null, null, "SQL");
                foreach (StockCardCls stockCard in this._StockCardDict.Values)
                    stockCard.Save();
            }
		}
		#endregion
	}
	#endregion
}
